/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "几何网格.h"
#include "节点/socket_utils.h"

#include <节点/插座/C_物体插座.h>
#include <节点/插座/list/list数值插座.h>
#include <节点/插座/list/list矢量插座.h>
#include <节点/插座/list/list物体插座.h>
#include <节点/插座/通用插座.h>
#include <节点/插座/几何插座.h>

#include <面/几何模型生成.h>


#include <Context/当前默认操作数据.h>
#include <Context/数据创建销毁.h>
#include <材质/预设材质.h>
#include <Range.h>
#include <JIT.h>

#include "节点/节点树.h"
#include "node后端.h"
#include "异步解算/物理异步解算.h"
#include "网格修改.h"



/*uvec2 f_多边形_添加顶点节点cxx(S_多边形 * self, void* verts) {
	auto& 顶点坐标 = *((std::vector<vec3>*)verts);
	auto& m_多边形 = *(self);

	uvec2 r;
	r.x = m_多边形.m_顶点.size();
	r.y = 顶点坐标.size();

	m_多边形.m_顶点.insert(m_多边形.m_顶点.end(), 顶点坐标.begin(), 顶点坐标.end());
	m_多边形.m_法线.resize(m_多边形.m_顶点.size());
	return r;
}*/



#define _DEF_变换插座创建_ DEF_创建Vec3插座_v1_I(L"位置"); DEF_创建Vec3插座_v1_I(L"旋转"); DEF_创建Vec3插座_v1_I(L"缩放");
#define _DEF_变换属性创建_										\
	if (m_Ob == nullptr) {										\
		m_Ob = f_node_网格节点创建物体数据(m_Ctx);				\
		f_get输出插座(1)->f_setData(m_Ob);						\
		f_NodeCtx_录物体类节点(this);							\
	}															\
	m_位置 = f_alloc_Vec3Prop(&m_Ob->m_变换.location, L"位置");	\
	m_旋转 = f_alloc_Vec3Prop(&m_Ob->m_变换.rotation, L"旋转");	\
	m_缩放 = f_alloc_Vec3Prop(&m_Ob->m_变换.scale, L"缩放");	\
	m_位置.m_私有 = true;										\
	m_旋转.m_私有 = true;										\
	m_缩放.m_私有 = true;										\


uvec2* f_多边形_边_data(S_边* self) {
	return self->edge.data();
}




C_网格节点::C_网格节点(S_设备环境 & ctx) : C_节点基类(DEF_网格节点, E_节点类型::e_节点Type_网格) {
	m_Ctx = ctx;
	m_Name = L"网格";
	m_Ob = nullptr;

	_DEF_变换属性创建_;
	f_node_物体加入全局容器中(m_Ob);

	C_插座基类* socket;
	DEF_创建UI32插座_I(L"数量");
	DEF_创建网格_1D插座_I(L"网格");

	DEF_创建网格_1D插座_O(L"新网格", ctx);

	DEF_UI32插座数据(f_get输入插座(1)) = 1;

}

C_网格节点::~C_网格节点() {
}

bool C_网格节点::f_update() {
	uint32 num = DEF_UI32插座数据(f_get输入插座(1));
	const auto& 要拷贝的网格 = *DEF_网格插座_1D数据(f_get输入插座(2), 0);

	auto* 新网格 = DEF_网格插座_1D数据(f_get输出插座(1), 0);
	auto* mesh = 新网格->ptr_userData;
	uint32 oldNum = 新网格->count;

	for (uint32 i = num; i < oldNum; ++i) {
		f_surface_释放网格(mesh[i]);
	}
	f_core_array_resize((S_Array*)新网格, num);
	mesh = mesh = 新网格->ptr_userData;

	for (uint32 i = oldNum; i < num; ++i) {
		mesh[i] = f_surface_创建网格对象(m_Ctx, E_网格数据枚举::e_Mesh_VULKAN);
	}

	uint32 要拷贝的网格数量 = 要拷贝的网格.count;
	if (要拷贝的网格数量) {
		auto* oldMesh = 要拷贝的网格.ptr_userData;
		if (要拷贝的网格数量 >= num) {
			for (uint32 i = 0; i < num; ++i) {
				f_surface_Copy(mesh[i], oldMesh[i]);
			}
		}
		else {
			for (uint32 i = 0; i < num; ++i) {
				f_surface_Copy(mesh[i], oldMesh[0]);
			}
		}
	}
	
	return false;
}

S_物体* C_网格节点::f_get虚拟体() {
	return m_Ob;
}

void C_网格节点::f_入回收() {
}

void C_网格节点::f_回收() {
}

void C_网格节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_网格节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

C_节点基类* f_node_创建网格节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_网格节点(ctx);
}

C_节点基类* f_node_载入网格节点(S_设备环境& ctx, FILE* f) {
	C_网格节点* node = new C_网格节点(ctx);
	return node;
}

void f_node_保存网格节点(C_节点基类* n, FILE* f) {
	C_网格节点* node = dynamic_cast<C_网格节点*>(n);
}







C_平面网格节点::C_平面网格节点(S_设备环境& ctx) : C_节点基类("平面网格节点", E_节点类型::e_节点Type_网格) {
	m_Ctx = ctx;
	m_Name = L"平面网格";
	m_Ob = nullptr;

	C_插座基类* socket;
	//_DEF_变换插座创建_
	DEF_创建Vec2插座_I(L"大小");
	DEF_创建uVec2插座_I(L"细分");

	DEF_创建物体插座_O(L"网格");



	vec2 size = { 1,1 };
	uvec2 细分 = { 1, 1 };
	f_get输入插座(1)->f_setData(&size);
	f_get输入插座(2)->f_setData(&细分);



	//m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	_DEF_变换属性创建_;
	f_node_物体加入全局容器中(m_Ob);
	//f_node_物体添加到主场景(m_Ob);
	f_get输出插座(1)->f_setData(m_Ob);
}

C_平面网格节点::~C_平面网格节点() {
}

bool C_平面网格节点::f_update() {
	
	auto& 大小 = DEF_Vec2插座数据(f_get输入插座(1), 0);
	auto& 细分 = DEF_uVec2插座数据(f_get输入插座(2));
	
	m_Ob->f_set位置(f_prop_Vec3(m_位置), 0);
	m_Ob->f_set旋转(f_prop_Vec3(m_旋转), 0);
	m_Ob->f_set缩放(f_prop_Vec3(m_缩放), 0);

	S_Mesh* mesh = f_ob_fromMesh(m_Ob, DEF_网格主数据层);
	std::vector<vec3> 顶点;
	std::vector<vec3> 法线;
	std::vector<vec2> UV;
	std::vector<uint32> 索引;
	f_graph_构建平面(大小, 细分, 顶点, 法线, UV, 索引);

	std::vector<S_VNT1> vnData;
	f_surface_数组合并(vnData, 顶点, 法线, UV);
	f_surface_fill顶点数据(mesh, vnData);
	f_surface_fill索引数据(mesh, 索引);

	m_Ob->m_Bound = f_surface_计算包围盒(mesh);
	f_get输出插座(1)->m_有新数据 = true;


	f_scene_更新物体渲染(f_NodeCtx_get默认场景(), nullptr);
	return false;
}

S_物体* C_平面网格节点::f_get虚拟体() {
	m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	return m_Ob;
}

void C_平面网格节点::f_入回收() {
	assert(m_Ob);
	f_NodeCtx_get默认场景()->f_remove物体(m_Ob, E_场景物体容器类型::e_集合);
}

void C_平面网格节点::f_回收() {
	f_NodeCtx_get默认场景()->f_add物体({ m_Ob }, E_场景物体容器类型::e_集合);
}

void C_平面网格节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_位置, f);
	f_prop_Load(m_旋转, f);
	f_prop_Load(m_缩放, f);

	f_ob_Load物体(m_Ob, f);
}

void C_平面网格节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_位置, f);
	f_prop_Save(m_旋转, f);
	f_prop_Save(m_缩放, f);

	f_ob_Save物体(m_Ob, f);
}

C_节点基类* f_node_创建平面网格节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_平面网格节点(ctx);
}

C_节点基类* f_node_载入平面网格节点(S_设备环境& ctx, FILE* f) {
	C_平面网格节点* node = new C_平面网格节点(ctx);
	return node;
}

void		f_node_保存平面网格节点(C_节点基类* n, FILE* f) {
	C_平面网格节点* node = dynamic_cast<C_平面网格节点*>(n);

}










C_球体网格节点::C_球体网格节点(S_设备环境& ctx) : C_节点基类("球体网格生成节点", E_节点类型::e_节点Type_网格) {
	m_Name = L"球体网格";
	m_Ctx = ctx;
	m_Ob = nullptr;

	C_插座基类* socket;
	//_DEF_变换插座创建_
	DEF_创建iVec2插座_I(L"细分");
	DEF_创建F32插座_v1_I(L"半径");

	DEF_创建物体插座_O(L"球体");



	auto& 经纬 = DEF_iVec2插座数据(f_get输入插座(1));
	auto& 半径 = DEF_F32插座数据(f_get输入插座(2));
	经纬 = { 32, 16 };
	半径 = 0.5;


	//m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	_DEF_变换属性创建_
	f_node_物体加入全局容器中(m_Ob);

	f_get输出插座(1)->f_setData(m_Ob);
}

C_球体网格节点::~C_球体网格节点() {
	f_node_从主场景移除物体({ m_Ob });
	f_node_物体从全局容器移除(m_Ob);
}

bool C_球体网格节点::f_update() {
	//const auto& 位置 = *DEF_Vec3插座数据(f_get输入插座(1), 0);
	//const auto& 旋转 = *DEF_Vec3插座数据(f_get输入插座(2), 0);
	//const auto& 缩放 = *DEF_Vec3插座数据(f_get输入插座(3), 0);
	const auto& 经纬 = DEF_iVec2插座数据(f_get输入插座(1));
	const auto& 半径 = DEF_F32插座数据(f_get输入插座(2));
	//m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	/*if (m_Ob == nullptr) {
		m_Ob = f_node_网格节点创建物体数据(m_Ctx);
		f_get输出插座(1)->f_setData(m_Ob);

		f_NodeCtx_录物体类节点(this);
	}
	m_Ob->f_set位置(位置, 0);
	m_Ob->f_set旋转(旋转, 0);
	m_Ob->f_set缩放(缩放, 0);*/
	m_Ob->f_set位置(f_prop_Vec3(m_位置), 0);
	m_Ob->f_set旋转(f_prop_Vec3(m_旋转), 0);
	m_Ob->f_set缩放(f_prop_Vec3(m_缩放), 0);

	S_Mesh* mesh = f_ob_fromMesh(m_Ob, DEF_网格主数据层);

	DEF_3Fs 顶点;
	DEF_3Fs 法线;
	DEF_2Fs UV;
	DEF_Is 索引;
	f_graph_构建球体(经纬.x, 经纬.y, 半径, 顶点, 法线, UV, 索引);

	std::vector<S_VNT1> vnData;
	f_surface_数组合并(vnData, 顶点, 法线, UV);
	f_surface_fill顶点数据(mesh, vnData);
	f_填充索引数据(mesh, 索引);

	m_Ob->m_Bound = f_surface_计算包围盒(mesh);
	f_get输出插座(1)->m_有新数据 = true;


	f_scene_更新物体渲染(f_NodeCtx_get默认场景(), nullptr);
	return false;
}

S_物体* C_球体网格节点::f_get虚拟体() {
	m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	return m_Ob;
}

void C_球体网格节点::f_入回收()
{
	assert(m_Ob);
	f_NodeCtx_get默认场景()->f_remove物体(m_Ob, E_场景物体容器类型::e_集合);
}

void C_球体网格节点::f_回收()
{
	f_NodeCtx_get默认场景()->f_add物体({ m_Ob }, E_场景物体容器类型::e_集合);
}

void C_球体网格节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_位置, f);
	f_prop_Load(m_旋转, f);
	f_prop_Load(m_缩放, f);

	f_ob_Load物体(m_Ob, f);
}

void C_球体网格节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_位置, f);
	f_prop_Save(m_旋转, f);
	f_prop_Save(m_缩放, f);

	f_ob_Save物体(m_Ob, f);
}

C_节点基类* f_node_创建球体网格节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_球体网格节点(ctx);
}

C_节点基类* f_node_载入球体网格节点(S_设备环境& ctx, FILE* f) {
	C_球体网格节点* node = new C_球体网格节点(ctx);
	return node;
}

void f_node_保存球体网格节点(C_节点基类* n, FILE* f) {
	C_平面网格节点* node = dynamic_cast<C_平面网格节点*>(n);
}











C_矩形网格节点::C_矩形网格节点(S_设备环境& ctx) : C_节点基类("矩形网格生成节点", E_节点类型::e_节点Type_网格) {
	m_Name = L"方体网格生成节点";
	m_Ctx = ctx;
	m_Ob = nullptr;

	C_插座基类* socket;
	DEF_创建Vec3插座_v1_I(L"大小");
	DEF_创建iVec3插座_I(L"细分");

	DEF_创建物体插座_O(L"方体");


	auto& 大小 = DEF_Vec3插座数据(f_get输入插座(1));
	auto& 细分 = DEF_iVec3插座数据(f_get输入插座(2));
	大小 = { 1, 1, 1 };
	细分 = { 1, 1, 1 };

	//m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	_DEF_变换属性创建_;
	f_node_物体加入全局容器中(m_Ob);

	f_get输出插座(1)->f_setData(m_Ob);
}

C_矩形网格节点::~C_矩形网格节点() {
}

bool C_矩形网格节点::f_update() {
	//const auto& 位置 = *DEF_Vec3插座数据(f_get输入插座(1), 0);
	//const auto& 旋转 = *DEF_Vec3插座数据(f_get输入插座(2), 0);
	//const auto& 缩放 = *DEF_Vec3插座数据(f_get输入插座(3), 0);
	const auto& 大小 = *DEF_iVec2插座_1D数据(f_get输入插座(1), 0);
	const auto& 细分 = *DEF_F32_Array1D插座数据(f_get输入插座(2), 0);
	/*m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	if (m_Ob == nullptr) {
		m_Ob = f_node_网格节点创建物体数据(m_Ctx);
		f_get输出插座(1)->f_setData(m_Ob);

		f_NodeCtx_录物体类节点(this);
	}
	m_Ob->f_set位置(位置, 0);
	m_Ob->f_set旋转(旋转, 0);
	m_Ob->f_set缩放(缩放, 0);*/

	m_Ob->f_set位置(f_prop_Vec3(m_位置), 0);
	m_Ob->f_set旋转(f_prop_Vec3(m_旋转), 0);
	m_Ob->f_set缩放(f_prop_Vec3(m_缩放), 0);

	S_Mesh* mesh = f_ob_fromMesh(m_Ob, DEF_网格主数据层);

	DEF_3Fs 顶点;
	DEF_3Fs 法线;
	DEF_2Fs UV;
	DEF_Is 索引;
	f_graph_构建立方体({ 1,1,1 }, { 1,1,1 }, 顶点, 法线, UV, 索引);


	std::vector<S_VNT1> vnData;
	f_surface_数组合并(vnData, 顶点, 法线, UV);
	f_surface_fill顶点数据(mesh, vnData);
	f_填充索引数据(mesh, 索引);

	m_Ob->m_Bound = f_surface_计算包围盒(mesh);
	f_get输出插座(1)->m_有新数据 = true;


	f_scene_更新物体渲染(f_NodeCtx_get默认场景(), nullptr);
	return false;
}


S_物体* C_矩形网格节点::f_get虚拟体() {
	m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	return m_Ob;
}

void C_矩形网格节点::f_入回收() {
	assert(m_Ob);
	f_NodeCtx_get默认场景()->f_remove物体(m_Ob, E_场景物体容器类型::e_集合);
}

void C_矩形网格节点::f_回收() {
	f_NodeCtx_get默认场景()->f_add物体({ m_Ob }, E_场景物体容器类型::e_集合);
}

void C_矩形网格节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	f_prop_Load(m_位置, f);
	f_prop_Load(m_旋转, f);
	f_prop_Load(m_缩放, f);

	f_ob_Load物体(m_Ob, f);
}

void C_矩形网格节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_位置, f);
	f_prop_Save(m_旋转, f);
	f_prop_Save(m_缩放, f);

	f_ob_Save物体(m_Ob, f);
}

C_节点基类* f_node_创建矩形网格节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_矩形网格节点(ctx);
}

C_节点基类* f_node_载入矩形网格节点(S_设备环境& ctx, FILE* f) {
	C_矩形网格节点* node = new C_矩形网格节点(ctx);
	return node;
}

void f_node_保存矩形网格节点(C_节点基类* n, FILE* f) {
	C_矩形网格节点* node = dynamic_cast<C_矩形网格节点*>(n);

}

















C_线框立方体节点::C_线框立方体节点(S_设备环境& ctx) : C_节点基类("线框立方体节点", E_节点类型::e_节点Type_网格) {
	m_Name = L"线框立方体";
	m_Ctx = ctx;

	m_Ob = nullptr;

	C_插座基类* socket;
	//_DEF_变换插座创建_;
	DEF_创建Vec3插座_v1_I(L"大小");
	DEF_创建uVec3插座_I(L"细分");

	DEF_创建物体插座_O(L"立方体");


	vec3 size = { 1,1, 1 };
	uvec3 细分 = { 1, 1, 1 };
	f_get输入插座(1)->f_setData(&size);
	f_get输入插座(2)->f_setData(&细分);


	//m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	_DEF_变换属性创建_;
	f_node_物体加入全局容器中(m_Ob);
	f_ob_set材质(m_Ob, f_NodeCtx_get逐顶点线段材质(), 0);
	f_ob_set材质(m_Ob, f_NodeCtx_get逐顶点线段材质(), 1);
	f_ob_set材质(m_Ob, f_NodeCtx_get逐顶点线段材质(), 2);

	f_get输出插座(1)->f_setData(m_Ob);
}

C_线框立方体节点::~C_线框立方体节点() {
	//C_节点基类::~C_节点基类();
}

bool C_线框立方体节点::f_update() {
	auto& 大小 = DEF_Vec3插座数据(f_get输入插座(1));
	auto& 细分 = *DEF_uVec3插座数据(f_get输入插座(2));
	//auto& mesh = *DEF_Mesh_插座数据(f_get输出插座(1));

	//auto 线材质 = new S_线逐顶点有色线段材质(m_Ctx, false);

	/*m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	if (m_Ob == nullptr) {
		m_Ob = f_node_线网格节点创建物体数据(m_Ctx);
		f_get输出插座(1)->f_setData(m_Ob);

		f_NodeCtx_录物体类节点(this);
	}
	m_Ob->f_set位置(位置, 0);
	m_Ob->f_set旋转(旋转, 0);
	m_Ob->f_set缩放(缩放, 0);*/
	m_Ob->f_set位置(f_prop_Vec3(m_位置), 0);
	m_Ob->f_set旋转(f_prop_Vec3(m_旋转), 0);
	m_Ob->f_set缩放(f_prop_Vec3(m_缩放), 0);

	S_Mesh* mesh = f_ob_fromMesh(m_Ob, DEF_网格主数据层);
	if (f_get输入插座(2)->m_有新数据) {
		std::vector<vec3> 顶点;
		std::vector<uint32> 索引;
		f_graph_构建立方体线框({ 1,1,1 }, { 1,1,1 }, 顶点, 索引);

		std::vector<S_VC> vnData;
		std::vector<S_RGBA8UI> 颜色 = f_range(顶点.size(), {0,0,0,255});
		f_surface_数组合并(vnData, 顶点, 颜色);

		f_surface_fill顶点数据(mesh, vnData);
		f_surface_fill索引数据(mesh, 索引);

		f_get输出插座(1)->m_有新数据 = true;
	}
	
	m_Ob->m_Bound = f_surface_计算包围盒(mesh);

	return false;
}

S_物体* C_线框立方体节点::f_get虚拟体() {
	m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	return m_Ob;
}

void C_线框立方体节点::f_入回收() {
	assert(m_Ob);
	f_NodeCtx_get默认场景()->f_remove物体(m_Ob, E_场景物体容器类型::e_集合);
}

void C_线框立方体节点::f_回收() {
	f_NodeCtx_get默认场景()->f_add物体({ m_Ob }, E_场景物体容器类型::e_集合);
}

void C_线框立方体节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_位置, f);
	f_prop_Load(m_旋转, f);
	f_prop_Load(m_缩放, f);

	f_ob_Load物体(m_Ob, f);
}

void C_线框立方体节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_位置, f);
	f_prop_Save(m_旋转, f);
	f_prop_Save(m_缩放, f);

	f_ob_Save物体(m_Ob, f);
}

C_节点基类* f_node_创建线框立方体节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_线框立方体节点(ctx);
}

C_节点基类* f_node_载入线框立方体节点(S_设备环境& ctx, FILE* f) {
	C_线框立方体节点* node = new C_线框立方体节点(ctx);
	return node;
}
void		f_node_保存线框立方体节点(C_节点基类* n, FILE* f) {
	C_线框立方体节点* node = dynamic_cast<C_线框立方体节点*>(n);
}




/*C_几何线节点::C_几何线节点(S_设备环境& ctx) : C_节点基类(DEF_几何节点, E_节点类型::e_节点Type_几何线) {
	m_Name = L"线";
	m_Ctx = ctx;

	m_Ob = f_node_网格节点创建物体数据(ctx);
}

C_几何线节点::~C_几何线节点() {
}

bool C_几何线节点::f_update() {
	return false;
}

S_物体* C_几何线节点::f_get虚拟体() {
	return m_Ob;
}

void C_几何线节点::f_入回收() {
	assert(m_Ob);
	f_NodeCtx_get默认场景()->f_remove物体(m_Ob, E_场景物体容器类型::e_集合);
}

void C_几何线节点::f_回收() {
	f_NodeCtx_get默认场景()->f_add物体({ m_Ob }, E_场景物体容器类型::e_集合);
}

C_节点基类* f_node_载入几何线节点(S_设备环境& ctx, FILE* f) {
	C_几何节点* node = new C_几何节点(ctx);
	return node;
}

void f_node_保存几何线节点(C_节点基类* n, FILE* f) {
	C_几何节点* node = dynamic_cast<C_几何节点*>(n);
}*/






C_几何节点::C_几何节点(S_设备环境& ctx, C_节点树* link_tree) : C_节点基类(DEF_几何节点, E_节点类型::e_节点Type_几何) {
	m_Name = L"几何网格";
	m_Ctx = ctx;

	m_Ob = nullptr;
	
	C_插座基类* socket;
	DEF_创建物体_1D插座_O(L"物体");

	if (link_tree) {
		
	}
	else {
		link_tree = f_node_Create几何节点树(false, L"geom_");
		
		auto 输入组节点 = new C_输入组节点(ctx);
		link_tree->f_添加节点(输入组节点);
		auto 输出组节点 = new C_输出组节点(ctx, 2);
		link_tree->f_添加节点(输出组节点);

		C_插座基类* socket = new C_多边形插座_1D(L"多边形");
		输出组节点->f_add插座(socket, E_插座方向::e_插座Type_输入, 1);

		输入组节点->m_插座可编辑 = true;
		//输出组节点->m_插座可编辑 = true;
	}

	f_绑定子集节点树(link_tree);
	f_绑定this节点树(link_tree);
	link_tree->f_set父节点(this);
	
	//m_更新方式 = E_节点更新方式::e_节点更新_逐帧;
	//m_函数名称 = f_alloc_StrProp(nullptr, L"函数名称");
	//m_函数名称.m_私有 = true;
	//f_prop_Str(m_函数名称) = C_节点树::g_函数名称分配.f_Gen(L"f_fun_geom");

	m_函数指针 = nullptr;

	m_数量 = f_alloc_UI32Prop(nullptr, L"数量", 1);
	m_数量.m_私有 = true;
	f_prop_UI32(m_数量) = 1;

	m_合并顶点 = f_alloc_BoolProp(nullptr, L"合并顶点");
	m_合并顶点.m_私有 = true;
	f_prop_Bool(m_合并顶点) = false;

	m_合并顶点阈 = f_alloc_F32Prop(nullptr, L"合并顶点阈");
	m_合并顶点阈.m_私有 = true;
	f_prop_F32(m_合并顶点阈) = 0.001;

	m_计算平滑法线 = f_alloc_BoolProp(nullptr, L"平滑法线");
	m_计算平滑法线.m_私有 = true;
	f_prop_Bool(m_计算平滑法线) = true;

	m_生成GPU网格 = f_alloc_BoolProp(nullptr, L"生成网格");
	m_生成GPU网格.m_私有 = true;
	f_prop_Bool(m_生成GPU网格) = true;


	f_prop_Bool(m_计算平滑法线) = false;
	f_prop_Bool(m_合并顶点) = true;
	f_prop_F32(m_合并顶点阈) = 0.001;


	m_是否链接 = false;
}

C_几何节点::~C_几何节点() {
	f_prop_Release(m_数量);
	f_prop_Release(m_合并顶点);
	f_prop_Release(m_合并顶点阈);
	f_prop_Release(m_计算平滑法线);
	//C_节点基类::~C_节点基类();

	for (auto& e : m_多边形) {
		f_surface_销毁多边形(e);
	}
	
}

bool C_几何节点::f_update() { 
	//return false;
	if (m_子集节点树->m_节点结构改变) {
		m_InNodes.clear();
		m_OutNudes.clear();
		f_get子集输入节点(m_InNodes);
		f_get子集输出节点(m_OutNudes);
	}
	
	

	for (auto& e : m_InNodes) {
		uint32 num = e->f_get输出插座Num();
		for (uint32 i = 0; i < num; ++i) {
			auto* socket = e->f_get输出插座(i);
			auto* inSocket = f_get输入插座(i);
			socket->f_setData(inSocket->f_getData(0));
		}
	}


	if (!m_子集节点树->m_程序集) {
		if (!m_子集节点树->m_开始编译) {
			m_子集节点树->f_准备编译节点树();

			m_子集节点树->m_开始编译 = true;
			f_NodeCtx_物理模拟线程入栈(this);
		}
		return true;
	}
	else if (m_子集节点树->m_程序集 && !m_函数指针) {
		std::string 函数名称 = f_WStringToString(m_子集节点树->m_IDName);
		E_JIT方式 方式 = (E_JIT方式)f_prop_enum(m_子集节点树->m_编译方式);
		m_函数指针 = (expand_接口函数_几何节点)f_JIT_取函数指针(m_子集节点树->m_程序集, 函数名称, 方式);
	}


	auto* socketOut1 = f_get输出插座(1);
	S_OBArray* obs = DEF_物体插座_1D数据(socketOut1, 0);
	uint32 多边形数量 = DEF_Max(f_prop_UI32(m_数量), 1);



	uint32 以有多边形数量 = m_多边形.size();
	auto* 多边形 = m_多边形.data();
#pragma omp parallel for
	for (int32 i = 0; i < 以有多边形数量; ++i) {
		f_surface_清除多边形元素(多边形[i]);
	}

	if (m_函数指针) {
		std::vector<void*> inData;
		uint32 inNum = f_get输入插座Num();
		uint32 outNum = f_get输出插座Num();
		for (uint32 i = 0; i < inNum; ++i) {
			inData.emplace_back(f_get输入插座(i)->f_getData(0));
		}
		for (uint32 i = 0; i < outNum; ++i) {
			inData.emplace_back(f_get输出插座(i)->f_getData(0));
		}
		
		uint32 已有数量 = m_多边形.size();
		for (uint32 i = 已有数量; i < 多边形数量; ++i) {
			m_多边形.push_back(f_surface_创建多边形());
		}

		
//#pragma omp parallel for num_threads(多边形数量)
		for (int32 i = 0; i < 多边形数量; ++i) {
			bool r = m_函数指针(m_多边形[i], i, inData.data(), C_节点树::g_节点JIT参数.data());
		}

		socketOut1->m_有新数据 = true;
	}
	else {
		m_Ob = nullptr;

		f_node_创建模型物体组(obs, 0, E_物体类型::t_多边形, m_Ctx);
		m_多边形.clear();

		return false;
	}
	


	f_node_创建模型物体组(obs, 多边形数量, E_物体类型::t_多边形, m_Ctx);
	if (f_prop_Bool(m_生成GPU网格) == false) {
		for (int32 polyID = 0; polyID < 多边形数量; ++polyID) {
			obs->ptr_userData[polyID]->m_UserData = m_多边形[polyID];
		}

		m_Ob = nullptr;
		return false;
	}


//#pragma omp parallel for num_threads(多边形数量)
	for (int32 polyID = 0; polyID < 多边形数量; ++polyID) {
		S_物体* Ob = obs->ptr_userData[polyID];
		
		std::vector<S_VC> 顶点;

#pragma omp parallel sections
		{
			#pragma omp section
			{
				uint32 num = m_多边形[polyID]->m_顶点.size();
				std::vector<S_VNT1> 面顶点(num);
				顶点.resize(num);
				auto* vert_ptr = 面顶点.data();
				for (uint32 i = 0; i < num; ++i) {
					顶点[i].vert = vert_ptr[i].vert = m_多边形[polyID]->m_顶点[i];
					顶点[i].color = f_PackData4X8({ 127, 200, 0, 255 });

					vert_ptr[i].normal = {};
					vert_ptr[i].UV = {};
				}

				
				

				num = m_多边形[polyID]->m_面.size();
				if (num) {
					auto* 面 = f_ob_fromMesh(Ob, DEF_网格主数据层);
					for (auto& e : 面->m_点自定义属性区间偏移) {
						f_buf_erase(e.second);
					}
					for (auto& e : 面->m_面自定义属性区间偏移) {
						f_buf_erase(e.second);
					}
					面->m_点自定义属性区间偏移.clear();
					面->m_面自定义属性区间偏移.clear();


					f_surface_fill顶点数据(面, 面顶点);
					f_surface_多边形三角化(面, m_多边形[polyID]);
					//f_surface_fill层纹理坐标(面, m_多边形[polyID].m_UV);

					//auto mat = f_mat44_identity();
					if (f_prop_Bool(m_计算平滑法线)) {
						std::vector<std::vector<uint32>> 顶点相邻面;
						f_surface_构建顶点相连面索引(面, 顶点相邻面);
						f_surface_计算面平滑法线(面, 顶点相邻面);
					}


					for (auto& e : m_多边形[polyID]->m_点自定义属性) {
						面->m_点自定义属性区间偏移[e.first] = f_surface_填充自定义属性(面, e.second, 0);
					}

				}

				

				f_surface_计算包围盒(f_ob_fromMesh(Ob, DEF_网格主数据层));
			}
            //#pragma omp section
			//{
			//}
		}

		uint32 边组数量 = m_多边形[polyID]->m_边.size();
		std::vector<S_VC> 顶点边;
		顶点边.reserve(边组数量 * 2);
		for (uint32 i = 0; i < 边组数量; ++i) {
			uint32 边数量 = m_多边形[polyID]->m_边[i]->edge.size();

			auto edge = m_多边形[polyID]->m_边[i]->edge.data();
			for (uint32 j = 0; j < 边数量; ++j) {
				uint32 id = i * 边数量 + j;
				S_VC v;
				v.vert = m_多边形[polyID]->m_顶点[edge[j].x];
				v.color = f_PackData4X8({ 0,0,0,255 });
				顶点边.push_back(v);

				v.vert = m_多边形[polyID]->m_顶点[edge[j].y];
				v.color = f_PackData4X8({ 0,0,0,255 });
				顶点边.push_back(v);
			}
		}
		auto* 线 = f_ob_fromMesh(Ob, 3);
		f_surface_fill顶点数据(线, 顶点边);


		auto* 点网格 = f_ob_fromMesh(Ob, 2);
		f_surface_fill顶点数据(点网格, 顶点);





		Ob->m_UserData = m_多边形[polyID];
		Ob->m_isUpdate = true;
		//f_NodeCtx_get默认场景()->f_add物体({ Ob }, E_场景物体容器类型::e_集合);
		f_scene_更新物体渲染(f_NodeCtx_get默认场景(), Ob);
	}
	
	m_Ob = obs->ptr_userData[0];
	return false;
}

std::string	C_几何节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	std::string code;

	std::string 函数名称 = f_WStringToString(m_子集节点树->m_IDName);
	//std::string 函数名称 = f_WStringToString(f_prop_Str(m_子集节点树->m_函数名称));
	if (!m_是否链接) {
		

		声明 += "static " DEF_S(DEF_编译全局可调参数) " = nullptr;\n";
		声明 += "static S_多边形* g多边形 = nullptr;\n";

		std::string extern_declspec = "extern \"C\" { __declspec(dllexport) ";
		code = " bool " + 函数名称;
		
		code += "(S_多边形* 多边形, int32 " + f_代码构建_ID变量名称(this) + ", void** inData, " DEF_S(DEF_编译可调参数) ")";
		
		声明 += extern_declspec + code + "; }\n";

		code += " { \n ";
		

		f_get子集输入节点(m_InNodes);
		f_get子集输入节点(m_OutNudes);

		uint32 inNum = f_get输入插座Num();
		uint32 outNum = f_get输出插座Num();
		for (auto& e : m_InNodes) {
			for (uint32 i = 0; i < inNum; ++i) {
				auto* socket = f_get输入插座(i);
				e->f_get输出插座(i)->f_setCode(f_代码构建_节点树输入输出变量引用(socket->m_Type, i));
			}
		}
		for (auto& e : m_OutNudes) {
			for (uint32 i = 0; i < outNum; ++i) {
				std::string 参数名称 = "*((" + f_node_getDataTypeName(e->f_get输入插座(i)->m_Type) + "*)(inData[" + f_整数值转字符串(i + inNum) + "]))";
				e->f_get输入插座(i)->f_setCode(参数名称);
			}
		}
		
		code += DEF_S(DEF_编译全局可调参数赋值)";\n";
		code += "g多边形 = 多边形;\n";
		code += f_NT_编译节点树(m_子集节点树, 定义, 声明);
		
		
		code += "return true;\n";

		code += "} \n ";

		定义.push_back(code);
	}

	if (f_NT_是否内联调用(this)) {
		//函数调用代码
		code = 函数名称;
		code += "(";

		uint32 num = f_get输入插座Num();
		for (uint32 i = 0; i < num; ++i) {
			auto* socket = f_get输入插座(i);
		}
		code += ");";
		return code;
	}

	return "";
}

void C_几何节点::f_异步解算() {
	//std::string 函数名称 = f_WStringToString(f_prop_Str(m_子集节点树->m_函数名称));
	std::string 函数名称 = f_WStringToString(m_子集节点树->m_IDName);
	E_JIT方式 方式 = (E_JIT方式)f_prop_enum(m_子集节点树->m_编译方式);

	m_函数指针 = nullptr;

	std::string path = S_节点数据::g_工程文件几何节点代码绝对路径 + 函数名称 + ".cpp";
	bool 编译成功 = f_NT_编译节点(this, path, false);

	switch (方式) {
	case E_JIT方式::e_jit_llvm: path = f_file_get路径(S_节点数据::g_工程文件几何节点代码绝对路径) + 函数名称 + ".bc"; break;
	case E_JIT方式::e_jit_dll: path = f_file_get路径(S_节点数据::g_工程文件几何节点代码绝对路径) + 函数名称 + ".ex"; break;
	}


	m_子集节点树->m_开始编译 = false;
	if (编译成功 && f_file_文件是否存在(path)) {
		m_子集节点树->m_程序集 = f_JIT_加载代码(path, 方式);

		m_函数指针 = (expand_接口函数_几何节点)f_NT_初始化函数接口(m_子集节点树->m_程序集, 函数名称, 方式);
		if (!m_函数指针) {
			return;
		}
	}
	else {
		f_node_销毁程序集(m_子集节点树);
		m_编译成功 = false;
		//m_函数指针 = (expand_接口函数_几何节点)f_JIT_取函数指针(m_子集节点树->m_程序集, 函数名称, 方式);
	}

	
	f_set是否要更新(true);
}

S_物体* C_几何节点::f_get虚拟体() {
	return m_Ob;
}

void C_几何节点::f_入回收() {
	assert(m_Ob);
	f_NodeCtx_get默认场景()->f_remove物体(m_Ob, E_场景物体容器类型::e_集合);
}

void C_几何节点::f_回收() {
	f_NodeCtx_get默认场景()->f_add物体({ m_Ob }, E_场景物体容器类型::e_集合);
}

void C_几何节点::f_get子集输入节点(std::vector<C_节点基类*>& inNodes) {
	inNodes.clear();
	for (auto& e : m_子集节点树->m_Nodes) {
		if (e->m_Type == E_节点类型::e_节点Type_组输入) {
			inNodes.emplace_back(e);
		}
	}
}

void C_几何节点::f_get子集输出节点(std::vector<C_节点基类*>& outNodes) {
	outNodes.clear();
	for (auto& e : m_子集节点树->m_Nodes) {
		if (e->m_Type == E_节点类型::e_节点Type_组输出) {
			outNodes.emplace_back(e);
		}
	}
}

void C_几何节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	
	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		switch (文件块.m_版本号) {
			case 0 << 32 | 0: {
				下一次读取数据指针 = f_prop_Load(m_数量, 下一次读取数据指针);
				下一次读取数据指针 = f_prop_Load(m_合并顶点, 下一次读取数据指针);
				下一次读取数据指针 = f_prop_Load(m_合并顶点阈, 下一次读取数据指针);
				下一次读取数据指针 = f_prop_Load(m_计算平滑法线, 下一次读取数据指针);
				下一次读取数据指针 = f_prop_Load(m_生成GPU网格, 下一次读取数据指针);

				break;
			}
			case 0 << 32 | 1: {
				const uint8* 下一次读取数据指针 = 文件块.m_data;

				下一次读取数据指针 = f_prop_Load(m_数量, 下一次读取数据指针);
				下一次读取数据指针 = f_prop_Load(m_合并顶点, 下一次读取数据指针);
				下一次读取数据指针 = f_prop_Load(m_合并顶点阈, 下一次读取数据指针);
				下一次读取数据指针 = f_prop_Load(m_计算平滑法线, 下一次读取数据指针);
				下一次读取数据指针 = f_prop_Load(m_生成GPU网格, 下一次读取数据指针);

				break;
			}
			default: {
				
			}
		}


		if (f_file_版本对比(文件块, S_节点数据::g_低版本号_4, S_节点数据::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_数量, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_合并顶点, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_合并顶点阈, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_计算平滑法线, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_生成GPU网格, 下一次读取数据指针);

			uint32 多边形数量 = f_prop_UI32(m_数量);
			S_OBArray* 物体 = DEF_物体插座_1D数据(f_get输出插座(1), 0);
			f_node_创建模型物体组(物体, 多边形数量, E_物体类型::t_多边形, m_Ctx);

			下一次读取数据指针 = f_ob_Load多物体(物体, 下一次读取数据指针);
		}
		else if (f_file_版本对比(文件块, S_节点数据::g_低版本号_3, S_节点数据::g_文件版本号)) {
			//下一次读取数据指针 = f_prop_Load(m_数量, 下一次读取数据指针);
			//下一次读取数据指针 = f_prop_Load(m_合并顶点, 下一次读取数据指针);
			//下一次读取数据指针 = f_prop_Load(m_合并顶点阈, 下一次读取数据指针);
			//下一次读取数据指针 = f_prop_Load(m_计算平滑法线, 下一次读取数据指针);
			//下一次读取数据指针 = f_prop_Load(m_生成GPU网格, 下一次读取数据指针);

			S_OBArray* 物体 = DEF_物体插座_1D数据(f_get输出插座(1), 0);
			f_ob_Load多物体(物体, f, m_Ctx);
			//f_ob_Load物体(m_Ob, f);
			for (uint32 i = 0; i < 物体->count; ++i) {
				f_node_构建多边形网格对象(m_Ctx, 物体->ptr_userData[i]);

				f_node_物体加入全局容器中(物体->ptr_userData[i]);
				f_node_物体添加到主场景(物体->ptr_userData[i]);
			}
		}
		
	}
	
	free(文件块.m_data);

	

	
}
void C_几何节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	
	S_文件块 文件块;
	文件块.m_块类型 = E_节点工程文件块类型::e_工程文件块_节点实例属性;
	文件块.m_版本号 = S_节点数据::g_文件版本号;

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_数量, 块);
	f_prop_Save(m_合并顶点, 块);
	f_prop_Save(m_合并顶点阈, 块);
	f_prop_Save(m_计算平滑法线, 块);
	f_prop_Save(m_生成GPU网格, 块);

	S_OBArray* obs = DEF_物体插座_1D数据(f_get输出插座(1), 0);
	f_ob_Save多物体(obs, 块);

	f_file_保存文件块(f, 文件块, 块);
	//f_ob_Save物体(m_Ob, f);
}

C_节点基类* f_node_创建几何节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_几何节点(ctx, 子节点树);
}

C_节点基类* f_node_载入几何节点(S_设备环境& ctx, FILE* f) {
	std::wstring 链接的节点树名称 = f_file_读取字符串(f);

	if (S_节点数据::G用于重新映射节点树到节点的容器.find(链接的节点树名称) == S_节点数据::G用于重新映射节点树到节点的容器.end()) {
		f_node_加载节点树(ctx, f);
	}

	C_几何节点* node = new C_几何节点(ctx, S_节点数据::G用于重新映射节点树到节点的容器[链接的节点树名称]);
	return node;
}

void f_node_保存几何节点(C_节点基类* n, FILE* f) {
	C_几何节点* node = dynamic_cast<C_几何节点*>(n);

	auto* tree = node->f_get子集树();
	f_file_保存字符串(f, tree->m_IDName);

	if (tree->m_未保存或加载) {
		tree->m_未保存或加载 = false;

		std::vector<C_节点树*> trees = { tree };
		f_node_保存节点树(trees, f);
	}
}





C_几何ID节点::C_几何ID节点(S_设备环境& ctx) : C_节点基类(DEF_几何ID节点) {
	m_Name = L"ID";
	m_Ctx = ctx;

	C_插座基类* socket;
	//DEF_创建Vec3_Array1D插座_I(L"顶点");
	//DEF_创建Vec3_Array1D插座_I(L"法线");
	//DEF_创建多边形面_1D插座_I(L"面");
	//DEF_创建多边形边_1D插座_I(L"边");
	DEF_创建I32插座_O(L"ID");

}

C_几何ID节点::~C_几何ID节点() {

}

bool C_几何ID节点::f_update() {
	return false;
}

std::string	C_几何ID节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	auto name = f_getName();

	name = f_代码构建_ID变量名称(f_getThis节点());
	
	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

C_节点基类* f_node_创建几何ID节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_几何ID节点(ctx);
}
C_节点基类* f_node_加载几何ID节点(S_设备环境& ctx, FILE* f) {
	C_几何ID节点* node = new C_几何ID节点(ctx);
	return node;
}
void		f_node_保存几何ID节点(C_节点基类* n, FILE* f) {
	C_几何ID节点* node = dynamic_cast<C_几何ID节点*>(n);
}




C_当前多边形节点::C_当前多边形节点(S_设备环境& ctx) : C_节点基类(DEF_当前多边形节点) {
	m_Name = L"多边形";
	m_Ctx = ctx;

	C_插座基类* socket;
	//DEF_创建Vec3_Array1D插座_I(L"顶点");
	//DEF_创建Vec3_Array1D插座_I(L"法线");
	//DEF_创建多边形面_1D插座_I(L"面");
	//DEF_创建多边形边_1D插座_I(L"边");
	DEF_创建多边形插座_O(L"多边形");

}

C_当前多边形节点::~C_当前多边形节点() {
}

bool C_当前多边形节点::f_update() {
	return false;
}

std::string	C_当前多边形节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	auto name = f_getName();

	name = "多边形";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

C_节点基类* f_node_创建当前多边形节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_当前多边形节点(ctx);
}
C_节点基类* f_node_加载当前多边形节点(S_设备环境& ctx, FILE* f) {
	C_当前多边形节点* node = new C_当前多边形节点(ctx);
	return node;
}
void		f_node_保存当前多边形节点(C_节点基类* n, FILE* f) {
	C_当前多边形节点* node = dynamic_cast<C_当前多边形节点*>(n);
}




C_构建多边形节点::C_构建多边形节点(S_设备环境& ctx) : C_节点基类(DEF_多边形节点, E_节点类型::e_节点Type_多边形) {
	m_Name = L"多边形";
	m_Ctx = ctx;
	m_Ob = f_node_网格节点创建物体数据(ctx);

	C_插座基类* socket;
	DEF_创建Vec3_Array1D插座_I(L"顶点");
	DEF_创建Vec3_Array1D插座_I(L"法线");
	DEF_创建多边形面_1D插座_I(L"面");
	DEF_创建多边形边_1D插座_I(L"边");

	DEF_创建多边形插座_O(L"多边形");
}

C_构建多边形节点::~C_构建多边形节点() {
	//C_节点基类::~C_节点基类();
}

bool C_构建多边形节点::f_update() {
	auto& 面 = *DEF_多边形面_1D插座数据(f_get输入插座(3), 0);
	auto& 边 = *DEF_多边形边_1D插座数据(f_get输入插座(4), 0);

	auto* 多边形 = DEF_多边形插座数据(f_get输出插座(2), 0);
	if (!多边形) {
		多边形 = new S_多边形;
		f_get输出插座(2)->f_setData(多边形);
	}

	return false;
}

C_节点基类* f_node_创建构建多边形节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_构建多边形节点(ctx);
}

C_节点基类* f_node_载入构建多边形节点(S_设备环境& ctx, FILE* f) {
	C_构建多边形节点* node = new C_构建多边形节点(ctx);
	return node;
}

void f_node_保存构建多边形节点(C_节点基类* n, FILE* f) {
	C_构建多边形节点* node = dynamic_cast<C_构建多边形节点*>(n);
}




C_多边形顶点节点::C_多边形顶点节点(S_设备环境& ctx) : C_节点基类(DEF_多边形顶点节点, E_节点类型::e_节点Type_多边形) {
	m_Name = L"顶点";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形面插座_O(L"面");
	DEF_创建Vec3_1D插座_O(L"顶点");

	m_Ob = f_node_网格节点创建物体数据(ctx);
}

C_多边形顶点节点::~C_多边形顶点节点() {
}

bool C_多边形顶点节点::f_update() {
	return false;
}

void C_多边形顶点节点::f_读取(FILE* f)
{
}

void C_多边形顶点节点::f_写入(FILE* f)
{
}

S_物体* C_多边形顶点节点::f_get虚拟体() {
	return m_Ob;
}

void C_多边形顶点节点::f_入回收() {
	assert(m_Ob);
	f_NodeCtx_get默认场景()->f_remove物体(m_Ob, E_场景物体容器类型::e_集合);
}

void C_多边形顶点节点::f_回收() {
	f_NodeCtx_get默认场景()->f_add物体({ m_Ob }, E_场景物体容器类型::e_集合);
}

C_节点基类* f_node_创建多边形顶点节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形顶点节点(ctx);
}

C_节点基类* f_node_载入多边形顶点节点(S_设备环境& ctx, FILE* f) {
	C_多边形顶点节点* node = new C_多边形顶点节点(ctx);
	return node;
}

void f_node_保存多边形顶点节点(C_节点基类* n, FILE* f) {
	C_多边形顶点节点* node = dynamic_cast<C_多边形顶点节点*>(n);
}





C_基本多边形节点::C_基本多边形节点(S_设备环境& ctx) : C_节点基类(DEF_基本多边形节点, E_节点类型::e_节点Type_多边形) {
	m_Ctx = ctx;
	m_Name = L"基本多边形";


	C_插座基类* socket;
	DEF_创建Vec3插座_I(L"大小", nullptr);
	DEF_创建uVec3插座_I(L"细分", nullptr);

	DEF_创建多边形元素插座_O(L"元素");


	DEF_Vec3插座数据(f_get输入插座(1)) = {1, 1, 1};
	(*DEF_uVec3插座数据(f_get输入插座(2), 0)) = {1, 1, 1};

	m_几何网格类型 = f_alloc_EnumProp(nullptr,
		//	0			1			2			3			4
		{ {L"平面", ""}, {L"球体", ""}, {L"方体", ""}, {L"圆柱", ""}, {L"圆面", ""}, },
		L"计算方式",
		0,
		nullptr
	);
	m_几何网格类型.m_私有 = true;

	m_加入到场景 = f_alloc_BoolProp(nullptr, L"加入到场景");
	m_加入到场景.m_私有 = true;
	f_prop_Bool(m_加入到场景) = false;
}

C_基本多边形节点::~C_基本多边形节点() {
	f_prop_Release(m_几何网格类型);
	f_prop_Release(m_加入到场景);
	//C_节点基类::~C_节点基类();
}

bool C_基本多边形节点::f_update() {
	return false;
}

std::string C_基本多边形节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();

	auto* rt = f_getThis节点树();
	auto 网格类型 = f_代码构建_属性变量(m_几何网格类型, rt);
	auto 加入到场景 = f_代码构建_属性变量(m_加入到场景, rt);
	
	m_Code += "S_多边形元素* " + name + ";\n";
	m_Code += "{\n";
	m_Code += f_get输入插座(1)->f_构建变量代码(0);
	m_Code += f_get输入插座(2)->f_构建变量代码(0);

	m_Code += name + " = " +  DEF_S(f_surface_构建预设多边形);
	m_Code += "(g多边形, " + f_get输入插座(2)->f_getCode(0) + ", " + f_get输入插座(1)->f_getCode(0) + ", " + 网格类型 + ");\n";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		//m_区域父节点->m_ReleaseCode += DEF_S(f_surface_销毁多边形元素);
		//m_区域父节点->m_ReleaseCode += "(" + name + ");\n";
		return "";
	}
	//释放 += DEF_S(f_surface_销毁多边形元素);
	//释放 += "(" + name + ");\n";
	return m_Code;
}

void C_基本多边形节点::f_Copy(const C_节点基类* node) {
	const C_基本多边形节点* 基本多边形节点 = dynamic_cast<const C_基本多边形节点*>(node);
	f_prop_enum(m_几何网格类型) = f_prop_enum(基本多边形节点->m_几何网格类型);
}

void C_基本多边形节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_几何网格类型, f);
	
}
void C_基本多边形节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_几何网格类型, f);
	
}

C_节点基类* f_node_创建基本多边形节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_基本多边形节点(ctx);
}

C_节点基类* f_node_载入基本多边形节点(S_设备环境& ctx, FILE* f) {
	C_基本多边形节点* node = new C_基本多边形节点(ctx);
	return node;
}

void f_node_保存基本多边形节点(C_节点基类* n, FILE* f) {
	C_基本多边形节点* node = dynamic_cast<C_基本多边形节点*>(n);
}




C_多边形添加顶点节点::C_多边形添加顶点节点(S_设备环境& ctx) : C_节点基类(DEF_多边形添加顶点节点, E_节点类型::e_节点Type_多边形) {
	m_Name = L"添加顶点";
	m_Ctx = ctx;
	m_Ob = f_node_网格节点创建点物体数据(ctx);

	C_插座基类* socket;
	DEF_创建多边形插座_I(L"多边形");
	DEF_创建Vec3_1D插座_I(L"坐标");
	DEF_创建uVec2插座_O(L"偏移");

}

C_多边形添加顶点节点::~C_多边形添加顶点节点() {
}

bool C_多边形添加顶点节点::f_update() {
	C_几何节点* gemo = dynamic_cast<C_几何节点*>(f_getThis节点());

	/*/const auto& vert = *DEF_Vec3_Array1D插座数据(f_get输入插座(1));
	auto* vert_ptr = vert.data();

	uvec2 r;
	r.x = gemo->m_多边形.m_顶点.size();
	r.y = vert.size();
	f_get输出插座(1)->f_setData(&r);

	gemo->m_多边形.m_顶点.insert(gemo->m_多边形.m_顶点.end(), vert.begin(), vert.end());

	std::vector<S_VC> 网格顶点(vert.size());
	for (uint32 i = 0; i < r.y; ++i) {
		S_VC v;
		v.vert = vert_ptr[i];
		v.color = f_PackData4X8({ 128,128,0,255 });
		网格顶点[i] = v;
	}

	auto* mesh = f_ob_fromMesh(m_Ob);
	f_surface_fill顶点数据(mesh, 网格顶点);*/

	return false;
}

std::string C_多边形添加顶点节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {

	m_ReleaseCode = "";
	m_Code = "";

	std::string code;
	code = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	m_Code += "uvec2 " + code + "{};\n";
	m_Code += "{\n";
	
	m_Code += socket2->f_构建变量代码(0);
	if (socket1->f_isLink()) {
		m_Code += socket1->f_构建变量代码(0);

		m_Code += code + " = ";
		m_Code += DEF_S(f_surface_添加多边形顶点);
		m_Code += "(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", nullptr);\n";
	}
	else {
		m_Code += code + " = ";
		m_Code += DEF_S(f_surface_添加多边形顶点);
		m_Code += "(g多边形, " + socket2->f_getCode(0) + ", nullptr);\n";
	}
	

	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(code);

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}

	return m_Code;
}

S_物体* C_多边形添加顶点节点::f_get虚拟体() {
	return nullptr;
	return m_Ob;
}

void C_多边形添加顶点节点::f_入回收() {
	assert(m_Ob);
	f_NodeCtx_get默认场景()->f_remove物体(m_Ob, E_场景物体容器类型::e_集合);
}

void C_多边形添加顶点节点::f_回收() {
	f_NodeCtx_get默认场景()->f_add物体({ m_Ob }, E_场景物体容器类型::e_集合);
}

C_节点基类* f_node_创建多边形添加顶点节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形添加顶点节点(ctx);
}

C_节点基类* f_node_载入多边形添加顶点节点(S_设备环境& ctx, FILE* f) {
	C_多边形添加顶点节点* node = new C_多边形添加顶点节点(ctx);
	return node;
}

void f_node_保存多边形添加顶点节点(C_节点基类* n, FILE* f) {
	C_多边形添加顶点节点* node = dynamic_cast<C_多边形添加顶点节点*>(n);
}




C_构建多边形边节点::C_构建多边形边节点(S_设备环境& ctx) : C_节点基类(DEF_多边形边节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"边";
	m_Ctx = ctx;
	m_Ob = f_node_网格节点创建线段物体数据(ctx);

	C_插座基类* socket;
	DEF_创建多边形插座_I(L"多边形");
	DEF_创建uVec2插座_I(L"偏移");

	DEF_创建多边形边插座_O(L"边索引");

	m_边模式 = f_alloc_EnumProp(nullptr, { 
		{L"连续", ""}, 
		{L"闭合", ""},
		{L"线段", ""},
	}, L"细分类型", 0);
	m_边模式.m_私有 = true;

	//m_边闭合 = f_alloc_BoolProp(nullptr, L"闭合");
	//m_边闭合.m_私有 = true;
	//f_prop_Bool(m_边闭合) = false;
}

C_构建多边形边节点::~C_构建多边形边节点() {
}

bool C_构建多边形边节点::f_update() {
	
	return false;
}

std::string C_构建多边形边节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	m_Code = "";
	m_ReleaseCode.clear();

	C_节点树* t = f_getThis节点树();
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	if (socket1->f_isLink()) {
		std::string name = f_getName();
		

		m_Code = "S_边* " + name + ";\n";
		m_Code += "{\n";
		m_Code += socket1->f_构建变量代码(0);
		m_Code += socket2->f_构建变量代码(0);

		m_Code += f_get输入插座(1)->f_构建变量代码(0);

		auto 边闭合 = f_代码构建_属性变量(m_边模式, t);

		m_Code += name + " = " + DEF_S(f_surface_添加多边形边) + "(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + 边闭合 + ");\n";

		m_Code += m_ReleaseCode;
		m_Code += "}\n";


		f_get输出插座(1)->f_setCode(name);
	}
	else {
		f_get输出插座(1)->f_setCode("");
	}

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}

	return m_Code;
}

S_物体* C_构建多边形边节点::f_get虚拟体() {
	return nullptr;
	return m_Ob;
}

void C_构建多边形边节点::f_入回收() {
	assert(m_Ob);
	f_NodeCtx_get默认场景()->f_remove物体(m_Ob, E_场景物体容器类型::e_集合);
}

void C_构建多边形边节点::f_回收() {
	return;
	f_NodeCtx_get默认场景()->f_add物体({ m_Ob }, E_场景物体容器类型::e_集合);
}

void C_构建多边形边节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_边模式, f);
}

void C_构建多边形边节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_边模式, f);
}

C_节点基类* f_node_创建构建多边形边节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_构建多边形边节点(ctx);
}

C_节点基类* f_node_载入构建多边形边节点(S_设备环境& ctx, FILE* f) {
	C_构建多边形边节点* node = new C_构建多边形边节点(ctx);
	return node;
}

void f_node_保存构建多边形边节点(C_节点基类* n, FILE* f) {
	C_构建多边形边节点* node = dynamic_cast<C_构建多边形边节点*>(n);
}




C_多边形索引节点::C_多边形索引节点(S_设备环境& ctx) : C_节点基类(DEF_多边形索引节点, E_节点类型::e_节点Type_多边形) {
	m_Name = L"取索引";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形元素插座_I(L"面");
	DEF_创建1D数组插座_O(L"索引");

}

C_多边形索引节点::~C_多边形索引节点() {
	//C_节点基类::~C_节点基类();
}

bool C_多边形索引节点::f_update() {
	return false;
}

std::string C_多边形索引节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();

	m_Code += DEF_S(S_1DArray);
	m_Code += "* " + name + ";\n";
	m_Code += "{\n";

	m_Code += name + " = (" + DEF_S(S_1DArray) + "*)";
	m_Code += DEF_S(f_core_array_new);
	m_Code += "(0, ";
	m_Code += DEF_S(sizeof(S_Array*));
	m_Code += ");\n";
	
	m_Code += f_get输入插座(1)->f_构建变量代码(0);
	m_Code += DEF_S(f_surface_取面索引);
	m_Code += "(g多边形, " + f_get输入插座(1)->f_getCode(0) + ", " + name + ");\n";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += DEF_S(f_surface_取面索引);
		m_区域父节点->m_ReleaseCode += "(nullptr, nullptr, " + name + ");\n";
		return "";
	}
	释放 += DEF_S(f_surface_取面索引);
	释放 += "(nullptr, nullptr, " + name + ");\n";
	return m_Code;
}

C_节点基类* f_node_创建多边形索引节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形索引节点(ctx);
}

C_节点基类* f_node_载入多边形索引节点(S_设备环境& ctx, FILE* f) {
	C_多边形索引节点* node = new C_多边形索引节点(ctx);
	return node;
}

void f_node_保存多边形索引节点(C_节点基类* n, FILE* f) {
	C_多边形索引节点* node = dynamic_cast<C_多边形索引节点*>(n);
}




C_投影纹理坐标节点::C_投影纹理坐标节点(S_设备环境& ctx) : C_节点基类(DEF_投影纹理坐标节点, E_节点类型::e_节点Type_空物体)  {
	m_Name = L"投影UV";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形元素插座_I(L"面");
	//DEF_创建Vec3插座_I(L"采样坐标", nullptr);
	//DEF_创建Vec3插座_I(L"方向", nullptr);
	//DEF_创建Vec3插座_I(L"位置", nullptr);
	DEF_创建Mat4X4插座_I(L"矩阵");

	DEF_创建iVec2_1D插座_O(L"UV索引");


	m_投影类型 = f_alloc_EnumProp(nullptr, {
		{L"平面", "平面"},
		{L"方体", "立体线框"},
		{L"球体", "球体"},
		{L"圆柱", "圆柱"},
		{L"等距圆柱", "世界"},
		}, L"投影类型");
	m_投影类型.m_私有 = true;
	f_prop_enum(m_投影类型) = 0;

	m_Ob = f_node_创建UV辅助操作虚拟体(ctx);
	f_node_设置UV操作虚拟体类型(m_Ob, 0);
	f_NodeCtx_录物体类节点(this, m_Ob);

	f_构建代码_分配渲染器GPU插座变量(*f_get输入插座(2));
	
}

C_投影纹理坐标节点::~C_投影纹理坐标节点() {
	f_构建代码_释放渲染器GPU插座变量(*f_get输入插座(2));
	f_prop_Release(m_投影类型);
}

bool C_投影纹理坐标节点::f_update() {
	return false;
}

std::string	C_投影纹理坐标节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();
	auto* rt = f_getThis节点树();

	switch (rt->m_树类型) {
	case E_节点树类型::e_type_着色节点树: {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Vec3);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec3);
		break;
	}
	default:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_多边形元素);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_iVec2_1D);
		break;
	}


	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	auto 投影类型 = f_代码构建_属性变量(m_投影类型, rt);

	switch (rt->m_树类型) {
	case E_节点树类型::e_type_着色节点树: {
		m_Code += "vec3 " + name + " = vec3(0);\n";

		if (!socket2->f_isLink()) {
			m_Ob->f_get矩阵2();
		}

		m_Code += "switch(" + 投影类型 + "){\n";
		m_Code += "case 0:\n";
		m_Code += name + " = vec3(f_CylindricalProjectUV(" + socket1->f_getCode(0) + "), 0);\n";
		m_Code += "break;\n";

		m_Code += "case 1:\n";
		m_Code += name + " = vec3(f_CylindricalProjectUV(" + socket1->f_getCode(0) + "), 0);\n";
		m_Code += "break;\n";

		m_Code += "case 2:\n";
		m_Code += name + " = vec3(f_CylindricalProjectUV(" + socket1->f_getCode(0) + "), 0);\n";
		m_Code += "break;\n";

		m_Code += "case 3:\n";
		m_Code += name + " = vec3(f_CylindricalProjectUV(" + socket1->f_getCode(0) + "), 0);\n";
		m_Code += "break;\n";

		m_Code += "case 4:\n";
		m_Code += name + " = vec3(f_CylindricalProjectUV(" + socket1->f_getCode(0) + "), 0);\n";
		m_Code += "break;\n";

		m_Code += "}\n";


		f_get输出插座(1)->f_setCode(name);
		if (m_区域父节点) {
			m_区域父节点->m_Code += m_Code;
			return "";
		}
		break;
	}
	default:
		m_Code += DEF_S(S_iVec2Array);
		m_Code += "* " + name + ";\n";
		m_Code += "{\n";

		m_Code += name + " = " + f_代码构建_创建Array(E_值类型::e_Type_iVec2_1D, "0");
		
		auto 变换物体指针 = f_代码构建_变量(f_getThis节点树(), m_Ob, E_值类型::e_Type_Object);
		m_Code += socket2->f_getCode(0) + " = " + DEF_S(f_ob_get变换矩阵) + "(&" + 变换物体指针 + ");\n";
		m_Code += DEF_S(f_surface_投影纹理坐标);
		m_Code += "(g多边形," + 投影类型 + ", " + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";

		m_Code += m_ReleaseCode;
		m_Code += "}\n";

		f_get输出插座(1)->f_setCode(name);
		if (m_区域父节点) {
			m_区域父节点->m_Code += m_Code;
			m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
			return "";
		}

		释放 += f_代码构建_销毁数组(name);
		break;
	}

	return m_Code;
}

S_物体* C_投影纹理坐标节点::f_get虚拟体() {
	//return nullptr;
	return m_Ob;
}

void C_投影纹理坐标节点::f_入回收() {
	f_NodeCtx_get默认场景()->f_remove物体(m_Ob, E_场景物体容器类型::e_集合);
}

void C_投影纹理坐标节点::f_回收() {
	f_NodeCtx_get默认场景()->f_add物体({ m_Ob }, E_场景物体容器类型::e_集合);
}

void C_投影纹理坐标节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_投影类型, f);
}

void C_投影纹理坐标节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_投影类型, f);
}

C_节点基类* f_node_创建投影纹理坐标节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_投影纹理坐标节点(ctx);
}

C_节点基类* f_node_载入投影纹理坐标节点(S_设备环境& ctx, FILE* f) {
	C_投影纹理坐标节点* node = new C_投影纹理坐标节点(ctx);
	return node;
}

void f_node_保存投影纹理坐标节点(C_节点基类* n, FILE* f) {
	C_投影纹理坐标节点* node = dynamic_cast<C_投影纹理坐标节点*>(n);
}




C_添加多边形元素节点::C_添加多边形元素节点(S_设备环境& ctx) : C_节点基类(DEF_添加多边形元素节点) {
	m_Name = L"添加面";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建Vec3_1D插座_I(L"点");
	DEF_创建UI32_1D插座_I(L"索引");
	DEF_创建uVec2_1D插座_I(L"环");

	DEF_创建多边形元素插座_O(L"元素");

	DEF_UI32插座_1D数据(f_get输入插座(2))->ptr_userData[0] = 0;
	DEF_uVec2插座_1D数据(f_get输入插座(3))->ptr_userData[0] = {};
}

bool C_添加多边形元素节点::f_update() {
	return false;
}

std::string	C_添加多边形元素节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);

	m_Code += DEF_S(S_多边形元素*)" " + name + ";\n";
	m_Code += "{\n";

	m_Code += name + " = ";
	m_Code += DEF_S(f_surface_添加多边形元素)"(g多边形, " + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ");\n";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		//m_区域父节点->m_ReleaseCode += DEF_S(f_surface_销毁多边形元素)"(" + name + ");\n";
		return "";
	}
	//释放 += DEF_S(f_surface_销毁多边形元素)"(" + name + ");\n";
	return m_Code;
}

C_节点基类* f_node_创建添加多边形元素节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_添加多边形元素节点(ctx);
}

C_节点基类* f_node_载入添加多边形元素节点(S_设备环境& ctx, FILE* f) {
	C_添加多边形元素节点* node = new C_添加多边形元素节点(ctx);
	return node;
}

void f_node_保存添加多边形元素节点(C_节点基类* n, FILE* f) {
	C_添加多边形元素节点* node = dynamic_cast<C_添加多边形元素节点*>(n);
}






C_添加纹理坐标节点::C_添加纹理坐标节点(S_设备环境& ctx) : C_节点基类(DEF_添加纹理坐标节点) {
	m_Name = L"添加纹理坐标";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建Vec2_1D插座_I(L"坐标");
	DEF_创建UI32_1D插座_I(L"索引");
	DEF_创建uVec2_1D插座_I(L"环");

	DEF_创建uVec2_1D插座_O(L"环");

}

C_添加纹理坐标节点::~C_添加纹理坐标节点() {
}

bool C_添加纹理坐标节点::f_update() {
	return false;
}

std::string	C_添加纹理坐标节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";

	std::string name = f_getName();
	m_Code += DEF_S(S_uVec2Array*)" " + name + ";\n";
	m_Code += "{\n";

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);

	m_Code += name + " = (S_uVec2Array*)f_core_array_from((S_Array*)" + socket3->f_getCode(0) + ");\n";
	m_Code += DEF_S(f_surface_添加多边形纹理坐标);
	m_Code += "(g多边形," + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + name + ");\n";
	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_添加纹理坐标节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_添加纹理坐标节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

C_节点基类* f_node_创建构建多边形纹理坐标节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_添加纹理坐标节点(ctx);
}

C_节点基类* f_node_载入构建多边形纹理坐标节点(S_设备环境& ctx, FILE* f) {
	C_添加纹理坐标节点* node = new C_添加纹理坐标节点(ctx);
	return node;
}

void f_node_保存构建多边形纹理坐标节点(C_节点基类* n, FILE* f) {
	C_添加纹理坐标节点* node = dynamic_cast<C_添加纹理坐标节点*>(n);
}




C_设置面材质槽ID节点::C_设置面材质槽ID节点(S_设备环境& ctx) : C_节点基类(DEF_设置面材质槽ID节点) {
	m_Name = L"设置面材质槽ID";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形元素插座_I(L"面");
	DEF_创建UI32_1D插座_I(L"槽ID");

	DEF_创建多边形元素插座_O(L"面");
	//DEF_创建多边形面插座_O(L"面");

}

C_设置面材质槽ID节点::~C_设置面材质槽ID节点() {
}

bool C_设置面材质槽ID节点::f_update() {
	return false;
}

std::string	C_设置面材质槽ID节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	//std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	switch (socket1->f_get接入的数据类型()) {
	case E_值类型::e_Type_多边形元素1D:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_多边形元素1D);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_多边形元素1D);
		break;
	default:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_多边形元素);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_多边形元素);
		break;
	}

	socket1 = f_get输入插座(1);
	socket2 = f_get输入插座(2);


	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);

	if (socket1->m_Type == E_值类型::e_Type_多边形元素1D) {
		m_Code += DEF_S(f_surface_设置元素组材质槽ID);
		m_Code += "(g多边形," + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
	}
	else {
		m_Code += DEF_S(f_surface_设置元素材质槽ID);
		m_Code += "(g多边形," + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
	}
	
	m_Code += m_ReleaseCode;
	m_Code += "}\n";


	
	f_get输出插座(1)->f_setCode(socket1->f_getCode(0));
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		//m_区域父节点->m_ReleaseCode += f_代码构建_销毁Array(name);
		return "";
	}
	//释放 += f_代码构建_销毁Array(name);
	return m_Code;
}

void C_设置面材质槽ID节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_设置面材质槽ID节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

C_节点基类* f_node_创建设置面材质槽ID节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_设置面材质槽ID节点(ctx);
}

C_节点基类* f_node_载入设置面材质槽ID节点(S_设备环境& ctx, FILE* f) {
	C_设置面材质槽ID节点* node = new C_设置面材质槽ID节点(ctx);
	return node;
}

void f_node_保存设置面材质槽ID节点(C_节点基类* n, FILE* f) {
	C_设置面材质槽ID节点* node = dynamic_cast<C_设置面材质槽ID节点*>(n);
}





C_网格采样节点::C_网格采样节点(S_设备环境& ctx) : C_节点基类(DEF_网格采样节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"网格采样";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建网格插座_I(L"网格");
	DEF_创建F32插座_v1_I(L"最小间隔");
	DEF_创建I32插座_I(L"随机种子");

	DEF_创建Vec3_1D插座_O(L"顶点");
	DEF_创建Vec3_1D插座_O(L"法线");


	//m_随机 = f_alloc_BoolProp(nullptr, L"随机");
	//m_随机.m_私有 = true;

	m_平滑法线 = f_alloc_BoolProp(nullptr, L"平滑法线");
	m_平滑法线.m_私有 = true;

}

C_网格采样节点::~C_网格采样节点() {
	f_prop_Release(m_平滑法线);
}

bool C_网格采样节点::f_update() {
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	float32 最小间隔 = DEF_F32插座数据(socket2);
	int32 随机种子 = DEF_I32插座数据(socket3);
	


	//std::vector<S_VN>& 采样坐标法线 = *DEF_VN_1D插座数据(f_get输出插座(1));
	//采样坐标法线.clear();

	if (f_get输入插座(1)->f_isLink() == false) {
		return false;
	}

	auto* mesh = DEF_网格插座数据(f_get输入插座(1));
	float32 间隔 = DEF_F32插座数据(f_get输入插座(2));

	if (mesh) {
		std::vector<S_VN> vn;
		std::vector<uvec3> i;
		f_surface_get顶点数据(mesh, vn);
		f_surface_get顶点索引(mesh, i);

		//f_graph_从面采样坐标(采样坐标法线, vn, i, 间隔 * 2);
	}
	else {
		//采样坐标法线.clear();
	}

	return false;
}

std::string	C_网格采样节点::DEF_节点编译函数 {
	m_ReleaseCode = "";
	m_Code = "";

	std::string name = f_getName();



	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		//m_区域父节点->m_ReleaseCode += f_代码构建_销毁Array(name);
		return "";
	}
	//释放 += f_代码构建_销毁Array(name);
	return m_Code;
}

void C_网格采样节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_平滑法线, f);
}

void C_网格采样节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_平滑法线, f);
}

C_节点基类* f_node_创建网格采样节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_网格采样节点(ctx);
}

C_节点基类* f_node_载入网格采样节点(S_设备环境& ctx, FILE* f) {
	C_网格采样节点* node = new C_网格采样节点(ctx);
	return node;
}

void f_node_保存网格采样节点(C_节点基类* n, FILE* f) {
	C_网格采样节点* node = dynamic_cast<C_网格采样节点*>(n);

}



C_拷贝网格数据节点::C_拷贝网格数据节点(S_设备环境& ctx) : C_节点基类(DEF_网格采样节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"网格采样";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建网格_1D插座_I(L"网格");
	DEF_创建网格_1D插座_I(L"源网格");
	DEF_创建网格_1D插座_O(L"网格");
}

C_拷贝网格数据节点::~C_拷贝网格数据节点() {
}

bool C_拷贝网格数据节点::f_update() {
	S_MeshArray* meshs_d = DEF_网格插座_1D数据(f_get输入插座(1), 0);
	S_MeshArray* meshs_s = DEF_网格插座_1D数据(f_get输入插座(2), 0);



	f_get输出插座(1)->f_setData(meshs_d);
	return false;
}

void C_拷贝网格数据节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_拷贝网格数据节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

C_节点基类* f_node_创建拷贝网格数据节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_拷贝网格数据节点(ctx);
}

C_节点基类* f_node_载入拷贝网格数据节点(S_设备环境& ctx, FILE* f) {
	C_拷贝网格数据节点* node = new C_拷贝网格数据节点(ctx);
	return node;
}

void		f_node_保存拷贝网格数据节点(C_节点基类* n, FILE* f) {
	C_拷贝网格数据节点* node = dynamic_cast<C_拷贝网格数据节点*>(n);
}



C_点在网格内节点::C_点在网格内节点(S_设备环境& ctx) : C_节点基类(DEF_取多边形面顶点节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"网格采样";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建网格_1D插座_I(L"网格");
	DEF_创建Vec3_1D插座_I(L"点");
	DEF_创建F32插座_I(L"边间隔", 0);

	DEF_创建Bool_1D插座_O(L"内外");


	m_反向 = f_alloc_BoolProp(nullptr, L"反向");
	m_反向.m_私有 = true;

}

C_点在网格内节点::~C_点在网格内节点() {
	f_prop_Release(m_反向);
}

bool C_点在网格内节点::f_update() {
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);



	return false;
}

std::string	C_点在网格内节点::DEF_节点编译函数 {
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	m_Code += DEF_S(S_Vec3Array*)" " + name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Bool_1D, "1") + ";\n";
	m_Code += "{\n";


	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_点在网格内节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		下一次读取数据指针 = f_prop_Load(m_反向, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_点在网格内节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_反向, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建点在网格内节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_点在网格内节点(ctx);
}

C_节点基类* f_node_载入点在网格内节点(S_设备环境& ctx, FILE* f) {
	C_点在网格内节点* node = new C_点在网格内节点(ctx);
	return node;
}

void		f_node_保存点在网格内节点(C_节点基类* n, FILE* f) {
	C_点在网格内节点* node = dynamic_cast<C_点在网格内节点*>(n);
}



void on_自定义属性名称PropUpdate(S_Props& prop) {
	prop.m_Name;

}

C_创建网格自定义属性节点::C_创建网格自定义属性节点(S_设备环境& ctx) : C_节点基类(DEF_创建网格自定义属性节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"创建自定义属性";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形插座_I(L"多边形");
	DEF_网格自定义属性插座_O(L"属性");
	//DEF_创建多边形插座_O(L"多边形");


	m_分布类型 = f_alloc_EnumProp(nullptr, {
		{L"点", ""},
		{L"面", ""},
		//{L"元素", ""},
	}, L"分布类型");
	m_分布类型.m_私有 = true;

	m_属性名称 = f_alloc_LineStrProp(nullptr, L"属性类型");
	m_属性名称.m_私有 = true;
	m_属性名称.m_UI->m_Update = on_自定义属性名称PropUpdate;


	m_属性类型 = f_alloc_EnumProp(nullptr, {
		//{L"i8", ""},
		//{L"ui8", ""},
		//{L"i16", ""},
		//{L"ui16", ""},
		{L"i32", ""},
		{L"ui32", ""},
		{L"f32", ""},
		//{L"i64", ""},
		{L"vec2", ""},
		{L"vec3", ""},
		{L"vec4", ""},
		{L"ivec4", ""},
							  }, L"属性类型");
	m_属性类型.m_私有 = true;

}

C_创建网格自定义属性节点::~C_创建网格自定义属性节点() {
	f_prop_Release(m_分布类型);
	f_prop_Release(m_属性名称);
	f_prop_Release(m_属性类型);
}

bool C_创建网格自定义属性节点::f_update() {
	auto* socket1 = f_get输入插座(1);
	//auto* socket2 = f_get输入插座(2);

	return false;
}

std::string	C_创建网格自定义属性节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	//auto* socket2 = f_get输入插座(2);

	//f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_F32_1D);
	//socket2 = f_get输入插座(2);


	//m_Code += DEF_S(S_Vec3Array*)" " + name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec3_1D, "1") + ";\n";
	m_Code += "{\n";


	S_网格自定义属性& 属性 = DEF_网格自定义属性插座数据(f_get输出插座(1));
	auto typeName = f_prop_enumName(m_属性类型);
	if (typeName == L"f32") {
		属性.m_Type = E_值类型::e_Type_F32_1D;
	}
	else if (typeName == L"i32") {
		属性.m_Type = E_值类型::e_Type_I32_1D;
	}
	else if (typeName == L"ui32") {
		属性.m_Type = E_值类型::e_Type_UI32_1D;
	}
	else if (typeName == L"vec2") {
		属性.m_Type = E_值类型::e_Type_Vec2_1D;
	}
	else if (typeName == L"vec3") {
		属性.m_Type = E_值类型::e_Type_Vec3_1D;
	}
	else if (typeName == L"vec4") {
		属性.m_Type = E_值类型::e_Type_Vec4_1D;
	}
	else if (typeName == L"ivec4") {
		属性.m_Type = E_值类型::e_Type_iVec4_1D;
	}

	属性.m_Name = &f_prop_LineStr(m_属性名称);
	属性.m_分布方式 = f_prop_enum(m_分布类型);

	//auto 属性名称 = f_代码构建_属性变量(m_属性名称, f_getThis节点树());
	auto 属性名称 = "((S_网格自定义属性*)" + DEF_指针到字符串(&属性) + ")";

	//m_Code += DEF_S(f_surface_创建自定义属性)"(" + socket1->f_getCode(0) + ", " + 属性名称 + ");\n";
	if (socket1->f_isLink()) {
		m_Code += DEF_S(f_surface_创建自定义属性)"(" + socket1->f_getCode(0) + ", " + 属性名称 + ");\n";
	}
	else {
		m_Code += DEF_S(f_surface_创建自定义属性)"(g多边形, (S_网格自定义属性*)" + DEF_指针到字符串(&属性) + ");\n";
	}
	
	
	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(属性名称);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		//m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	//释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_创建网格自定义属性节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		下一次读取数据指针 = f_prop_Load(m_分布类型, 下一次读取数据指针);
		下一次读取数据指针 = f_prop_Load(m_属性名称, 下一次读取数据指针);
		下一次读取数据指针 = f_prop_Load(m_属性类型, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_创建网格自定义属性节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_分布类型, 块);
	f_prop_Save(m_属性名称, 块);
	f_prop_Save(m_属性类型, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建网格自定义属性节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_创建网格自定义属性节点(ctx);
}

C_节点基类* f_node_加载网格自定义属性节点(S_设备环境& ctx, FILE* f) {
	C_创建网格自定义属性节点* node = new C_创建网格自定义属性节点(ctx);
	return node;
}

void		f_node_保存网格自定义属性节点(C_节点基类* n, FILE* f) {
	C_创建网格自定义属性节点* node = dynamic_cast<C_创建网格自定义属性节点*>(n);
}





C_设置网格面自定义属性节点::C_设置网格面自定义属性节点(S_设备环境& ctx) : C_节点基类(DEF_设置网格面自定义属性节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"设置自定义属性";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形元素插座_I(L"面");
	DEF_网格自定义属性插座_I(L"属性");
	DEF_创建数组插座_I(L"值");

	DEF_创建多边形元素插座_O(L"面");

	m_元素类型 = f_alloc_EnumProp(nullptr, {
		{L"面", ""},
		{L"元素", ""},
	}, L"元素类型");
	m_元素类型.m_私有 = true;

}

C_设置网格面自定义属性节点::~C_设置网格面自定义属性节点() {
	f_prop_Release(m_元素类型);
}

bool C_设置网格面自定义属性节点::f_update() {
	auto* socket1 = f_get输入插座(1);
	//auto* socket2 = f_get输入插座(2);

	return false;
}

std::string	C_设置网格面自定义属性节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();


	switch (f_prop_enum(m_元素类型)) {
		case 0:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_多边形元素);
			break;
		case 1:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_多边形元素1D);
			break;
	}
	
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);


	S_网格自定义属性& 属性 = DEF_网格自定义属性插座数据(socket2);
	if (属性.m_Type) {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 3, 属性.m_Type);
		auto* socket3 = f_get输入插座(3);

		//f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_F32_1D);
		//socket2 = f_get输入插座(2);

		//m_Code += DEF_S(S_Vec3Array*)" " + name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec3_1D, "1") + ";\n";
		m_Code += "{\n";
		m_Code += socket1->f_构建变量代码(0);
		m_Code += socket2->f_构建变量代码(0);
		m_Code += socket3->f_构建变量代码(0);

		switch (f_prop_enum(m_元素类型)) {
			case 0:
				m_Code += DEF_S(f_surface_设置面自定义属性)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", (S_Array*)" + socket3->f_getCode(0) + ");\n";
				break;
			case 1:
				m_Code += DEF_S(f_surface_设置元素自定义属性)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", (S_Array*)" + socket3->f_getCode(0) + ");\n";
				break;
		}
		

		m_Code += "}\n";
	}
	

	f_get输出插座(1)->f_setCode(socket1->f_getCode(0));
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_设置网格面自定义属性节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		f_prop_Load(m_元素类型, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_设置网格面自定义属性节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_元素类型, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建设置网格自定义属性节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_设置网格面自定义属性节点(ctx);
}

C_节点基类* f_node_加载设置网格自定义属性节点(S_设备环境& ctx, FILE* f) {
	C_设置网格面自定义属性节点* node = new C_设置网格面自定义属性节点(ctx);
	return node;
}

void		f_node_保存设置网格自定义属性节点(C_节点基类* n, FILE* f) {
	C_设置网格面自定义属性节点* node = dynamic_cast<C_设置网格面自定义属性节点*>(n);
}





//C_设置网格元素自定义属性节点::C_设置网格元素自定义属性节点(S_设备环境& ctx) : C_节点基类(DEF_设置网格面自定义属性节点, E_节点类型::e_节点Type_网格) {
//	m_Name = L"设置自定义属性";
//	m_Ctx = ctx;
//
//	C_插座基类* socket;
//	DEF_创建多边形元素_1D插座_I(L"面");
//	DEF_网格自定义属性插座_I(L"属性");
//	DEF_创建数组插座_I(L"值");
//
//	DEF_创建多边形元素插座_O(L"面");
//
//}
//
//C_设置网格元素自定义属性节点::~C_设置网格元素自定义属性节点() {
//
//}
//
//bool C_设置网格元素自定义属性节点::f_update() {
//	auto* socket1 = f_get输入插座(1);
//	//auto* socket2 = f_get输入插座(2);
//
//	return false;
//}
//
//std::string	C_设置网格元素自定义属性节点::DEF_节点编译函数{
//	m_ReleaseCode = "";
//	m_Code = "";
//	std::string name = f_getName();
//
//	auto* socket1 = f_get输入插座(1);
//	auto* socket2 = f_get输入插座(2);
//
//
//	f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_多边形元素);
//
//	S_网格自定义属性& 属性 = DEF_网格自定义属性插座数据(socket2);
//	if (属性.m_Type) {
//		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 3, 属性.m_Type);
//		auto* socket3 = f_get输入插座(3);
//
//		//f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_F32_1D);
//		//socket2 = f_get输入插座(2);
//
//		//m_Code += DEF_S(S_Vec3Array*)" " + name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec3_1D, "1") + ";\n";
//		m_Code += "{\n";
//		m_Code += socket1->f_构建变量代码(0);
//		m_Code += socket2->f_构建变量代码(0);
//		m_Code += socket3->f_构建变量代码(0);
//
//		m_Code += DEF_S(f_surface_设置面自定义属性)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", (S_Array*)" + socket3->f_getCode(0) + ");\n";
//
//		m_Code += "}\n";
//	}
//
//
//	f_get输出插座(1)->f_setCode(socket1->f_getCode(0));
//	if (m_区域父节点) {
//		m_区域父节点->m_Code += m_Code;
//		return "";
//	}
//	return m_Code;
//}
//
//void C_设置网格元素自定义属性节点::f_读取(FILE* f) {
//	C_节点基类::f_读取(f);
//	auto 文件块 = f_file_读取文件块(f);
//
//	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
//		const uint8* 下一次读取数据指针 = 文件块.m_data;
//		//f_prop_Load(m_分布类型, 下一次读取数据指针);
//	}
//
//	free(文件块.m_data);
//}
//
//void C_设置网格元素自定义属性节点::f_写入(FILE* f) {
//	C_节点基类::f_写入(f);
//	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
//
//	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
//	//f_prop_Save(m_分布类型, 块);
//
//	f_file_保存文件块(f, 文件块, 块);
//}
//
//C_节点基类* f_node_创建设置网格自定义属性节点(S_设备环境& ctx, C_节点树* 子节点树) {
//	return new C_设置网格元素自定义属性节点(ctx);
//}
//
//C_节点基类* f_node_加载设置网格自定义属性节点(S_设备环境& ctx, FILE* f) {
//	C_设置网格元素自定义属性节点* node = new C_设置网格元素自定义属性节点(ctx);
//	return node;
//}
//
//void f_node_保存设置网格自定义属性节点(C_节点基类* n, FILE* f) {
//	C_设置网格元素自定义属性节点* node = dynamic_cast<C_设置网格元素自定义属性节点*>(n);
//}







